|
|
|
|
|
|
|
Windows内核调试
帖子发起人: holly 发起时间: 2008-12-02 12:58 下午 回复: 9
|
帖子排序:
|
|
|
|
2008-12-02, 14:28 下午
|
MJ0011
注册: 2008-04-24
发 贴: 112
|
|
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-12-02, 14:44 下午
|
王宇
注册: 2007-05-08
发 贴: 306
|
|
|
ULONG KeSuspendThread ( __inout PKTHREAD Thread )
/*++
Routine Description:
This function suspends the execution of a thread. If the suspend count overflows the maximum suspend count, then a condition is raised.
Arguments:
Thread - Supplies a pointer to a dispatcher object of type thread.
Return Value:
The previous suspend count.
--*/
NTSTATUS PsSuspendThread ( IN PETHREAD Thread, OUT PULONG PreviousSuspendCount OPTIONAL )
/*++
Routine Description:
This function suspends the target thread, and optionally returns the previous suspend count.
Arguments:
ThreadHandle - Supplies a handle to the thread object to suspend.
PreviousSuspendCount - An optional parameter, that if specified points to a variable that receives the thread's previous suspend count.
Return Value:
NTSTATUS - Status of call
--*/
利用结合反汇编的暴力搜索定位,比如:
0: kd> u nt!NtSuspendThread nt!NtSuspendThread: 805d58b0 6a20 push 20h 805d58b2 68f8b94d80 push offset nt!ObWatchHandles+0x79c (804db9f8) 805d58b7 e8c472f6ff call nt!_SEH_prolog (8053cb80) 805d58bc 33db xor ebx,ebx 805d58be 895dfc mov dword ptr [ebp-4],ebx 805d58c1 64a124010000 mov eax,dword ptr fs:[00000124h] 805d58c7 8945d0 mov dword ptr [ebp-30h],eax 805d58ca 8a8040010000 mov al,byte ptr [eax+140h] 805d58d0 8845e0 mov byte ptr [ebp-20h],al 805d58d3 8b750c mov esi,dword ptr [ebp+0Ch] 805d58d6 3ac3 cmp al,bl 805d58d8 7413 je nt!NtSuspendThread+0x3d (805d58ed) 805d58da 3bf3 cmp esi,ebx 805d58dc 740f je nt!NtSuspendThread+0x3d (805d58ed) 805d58de a134315680 mov eax,dword ptr [nt!MmUserProbeAddress (80563134)] 805d58e3 3bf0 cmp esi,eax 805d58e5 7202 jb nt!NtSuspendThread+0x39 (805d58e9) 805d58e7 8918 mov dword ptr [eax],ebx 805d58e9 8b06 mov eax,dword ptr [esi] 805d58eb 8906 mov dword ptr [esi],eax 805d58ed 834dfcff or dword ptr [ebp-4],0FFFFFFFFh 805d58f1 53 push ebx 805d58f2 8d45e4 lea eax,[ebp-1Ch] 805d58f5 50 push eax 805d58f6 ff75e0 push dword ptr [ebp-20h] 805d58f9 ff35bc495680 push dword ptr [nt!PsThreadType (805649bc)] 805d58ff 6a02 push 2 805d5901 ff7508 push dword ptr [ebp+8] 805d5904 e8896bfeff call nt!ObReferenceObjectByHandle (805bc492) 805d5909 3bc3 cmp eax,ebx 805d590b 7c5c jl nt!NtSuspendThread+0xb9 (805d5969) 805d590d 8d45dc lea eax,[ebp-24h] 805d5910 50 push eax 805d5911 ff75e4 push dword ptr [ebp-1Ch] 805d5914 e869feffff call nt!PsSuspendThread (805d5782) // 第三个 E8 类型 call 805d5919 8bf8 mov edi,eax 805d591b 8b4de4 mov ecx,dword ptr [ebp-1Ch]
0: kd> u nt!PsSuspendThread nt!PsSuspendThread: 805d5782 6a18 push 18h 805d5784 68e0b94d80 push offset nt!ObWatchHandles+0x784 (804db9e0) 805d5789 e8f273f6ff call nt!_SEH_prolog (8053cb80) 805d578e 33f6 xor esi,esi 805d5790 8975e4 mov dword ptr [ebp-1Ch],esi 805d5793 64a124010000 mov eax,dword ptr fs:[00000124h] 805d5799 8b7d08 mov edi,dword ptr [ebp+8] 805d579c 3bf8 cmp edi,eax 805d579e 752e jne nt!PsSuspendThread+0x4c (805d57ce) 805d57a0 8975fc mov dword ptr [ebp-4],esi 805d57a3 57 push edi 805d57a4 e83f8df2ff call nt!KeSuspendThread (804fe4e8) // 第二个 E8 类型 call 805d57a9 8945e4 mov dword ptr [ebp-1Ch],eax 805d57ac 8975dc mov dword ptr [ebp-24h],esi 805d57af 834dfcff or dword ptr [ebp-4],0FFFFFFFFh 805d57b3 e98a000000 jmp nt!PsSuspendThread+0xc0 (805d5842)
0: kd> u 804fe4e8 nt!KeSuspendThread: 804fe4e8 8bff mov edi,edi 804fe4ea 55 push ebp 804fe4eb 8bec mov ebp,esp 804fe4ed 83ec0c sub esp,0Ch 804fe4f0 53 push ebx 804fe4f1 56 push esi 804fe4f2 8b7508 mov esi,dword ptr [ebp+8] 804fe4f5 57 push edi ........
最后,马甲同学的惯用手法就是: __asm { mov ebx, g_Addr push xxx push xxx .... call ebx }
1. 相对偏移需要自己计算一下 如果要 E8 类型 call hook 之类的话 2. 我个人极不推荐这种做法
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-12-02, 15:26 下午
|
手语
注册: 2008-06-06
发 贴: 73
|
|
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-12-03, 14:56 下午
|
holly
注册: 2008-07-14
发 贴: 22
|
|
|
汗颜,不知道怎么在代码中能够搞定这种事!
~~~~~~~~~
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-12-03, 16:43 下午
|
王宇
注册: 2007-05-08
发 贴: 306
|
|
|
暴力不难呀。
nt!NtSuspendThread 是 SSDT 表里的 API:
0: kd> u nt!ZwSuspendThread nt!ZwSuspendThread: 80502104 b8fe000000 mov eax,0FEh 80502109 8d542404 lea edx,[esp+4] 8050210d 9c pushfd 8050210e 6a08 push 8 80502110 e83c030400 call nt!KiSystemService (80542451) 80502115 c20800 ret 8
0: kd> ?poi(80505450+0FE*4) Evaluate expression: -2141366096 = 805d58b0
0: kd> ln 805d58b0 (805d58b0) nt!NtSuspendThread | (805d5976) nt!NtResumeThread Exact matches: nt!NtSuspendThread = <no type information>
如果怕取的不正确就自己Map一份内核取到正确的地址。
然后开始反汇编这个地址,类似于下面的代码:
TotalSize = SizeOfProc( pTarFunction );
while( TRUE ) { if( CodeSize >= TotalSize ) break;
Size = SizeOfCode( (PVOID) pTarget, &pOpcode );
pTarget += Size; CodeSize += Size;
if( EnpCodeAnalysis(pOpcode, Size, CodeSize, TotalSize, HookNumber) ) { if( !gs_TargetAnalysis.Types ) INLINE_DBGPRINT( ("[keenjoy95 's Inline Hook Engine] - ERROR CODE 0xA0000001.\n") );
break; } }
明眼人一看就知道我这段代码用的是 Ms-Rem 的 反汇编引擎 LDasm,当然我自己的反汇编引擎也在编写中。
连续三次分析到长度为 5字节、E8 开头的指令就说明找到了 nt!PsSuspendThread,接下来找 nt!KeSuspendThread 的过程雷同。跳过 E8 是偏移 fff28d3f,需要计算一下。
我之所以不推荐这种方法的问题之一是跨平台,我简单看了一下,WIN-XP/2003/VISTA 下第三个 call 均是 nt!PsSuspendThread。
Windows 2000 Kernel Version 2195 (Service Pack 4) MP (2 procs) Free x86 下第三个 call 直接就是 nt!KeSuspendThread:
0: kd> u nt!NtSuspendThread nt!NtSuspendThread: 804e6462 55 push ebp 804e6463 8bec mov ebp,esp 804e6465 6aff push 0FFFFFFFFh 804e6467 6828664080 push offset nt!GUID_DEVICE_BATTERY+0x4b0 (80406628) 804e646c 68d00a4680 push offset nt!_except_handler3 (80460ad0) 804e6471 64a100000000 mov eax,dword ptr fs:[00000000h] 804e6477 50 push eax 804e6478 64892500000000 mov dword ptr fs:[0],esp 804e647f 51 push ecx 804e6480 51 push ecx 804e6481 83ec20 sub esp,20h 804e6484 53 push ebx 804e6485 56 push esi 804e6486 57 push edi 804e6487 8965e8 mov dword ptr [ebp-18h],esp 804e648a 8365fc00 and dword ptr [ebp-4],0 804e648e 64a124010000 mov eax,dword ptr fs:[00000124h] 804e6494 8945cc mov dword ptr [ebp-34h],eax 804e6497 8a8034010000 mov al,byte ptr [eax+134h] 804e649d 8845d8 mov byte ptr [ebp-28h],al 804e64a0 84c0 test al,al 804e64a2 8b750c mov esi,dword ptr [ebp+0Ch] 804e64a5 7417 je nt!NtSuspendThread+0x5c (804e64be) 804e64a7 85f6 test esi,esi 804e64a9 7413 je nt!NtSuspendThread+0x5c (804e64be) 804e64ab a178474880 mov eax,dword ptr [nt!MmUserProbeAddress (80484778)] 804e64b0 3bf0 cmp esi,eax 804e64b2 7206 jb nt!NtSuspendThread+0x58 (804e64ba) 804e64b4 c70000000000 mov dword ptr [eax],0 804e64ba 8b06 mov eax,dword ptr [esi] 804e64bc 8906 mov dword ptr [esi],eax 804e64be 834dfcff or dword ptr [ebp-4],0FFFFFFFFh 804e64c2 6a00 push 0 804e64c4 8d45dc lea eax,[ebp-24h] 804e64c7 50 push eax 804e64c8 ff75d8 push dword ptr [ebp-28h] 804e64cb ff35285c4880 push dword ptr [nt!PsThreadType (80485c28)] 804e64d1 6a02 push 2 804e64d3 ff7508 push dword ptr [ebp+8] 804e64d6 e8e78ff6ff call nt!ObReferenceObjectByHandle (8044f4c2) 804e64db 85c0 test eax,eax 804e64dd 0f8c9a000000 jl nt!NtSuspendThread+0x11b (804e657d) 804e64e3 c745fc01000000 mov dword ptr [ebp-4],1 804e64ea 64a124010000 mov eax,dword ptr fs:[00000124h] 804e64f0 8945c8 mov dword ptr [ebp-38h],eax 804e64f3 8b4ddc mov ecx,dword ptr [ebp-24h] 804e64f6 3bc8 cmp ecx,eax 804e64f8 7419 je nt!NtSuspendThread+0xb1 (804e6513) 804e64fa 83b92402000000 cmp dword ptr [ecx+224h],0 804e6501 7410 je nt!NtSuspendThread+0xb1 (804e6513) 804e6503 e89a92f6ff call nt!ObfDereferenceObject (8044f7a2) 804e6508 834dfcff or dword ptr [ebp-4],0FFFFFFFFh 804e650c b84b0000c0 mov eax,0C000004Bh 804e6511 eb6a jmp nt!NtSuspendThread+0x11b (804e657d) 804e6513 51 push ecx 804e6514 e86980f4ff call nt!KeSuspendThread (8042e582)
另外就是绕开入口函数直接调用 internal 实现有时往往会有一些问题。 比如外层函数修改了某些标志位再 call 的 internal_xxx,那么我们就需要手动设置这些标志位 等。
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-12-03, 18:56 下午
|
skyworth
注册: 2008-06-07
发 贴: 55
|
|
|
直接调用未公开的函数不太好吧,既然未公开,那就不能确定微软会不会在某个时候改掉,然后就挂了……
个人觉得调用未公开的函数拿来练手是不错的,要是用在产品里,就不太合适了。
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-12-05, 13:58 下午
|
王宇
注册: 2007-05-08
发 贴: 306
|
|
|
上述暴力搜索解法是我不推荐的
我推荐的解法是栈回溯
但是至于如何回溯查找往往需要特别对待... ;)
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-12-05, 20:13 下午
|
MJ0011
注册: 2008-04-24
发 贴: 112
|
|
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-12-06, 11:59 上午
|
holly
注册: 2008-07-14
发 贴: 22
|
|
|
内功不够深,打不通反汇编的任督二脉!
道理是懂了!~~~
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
高端调试 » 软件调试 » Windows内核调试 » 求教:如何调用内核未引出的函数!
|
|
|
|
|
|